﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using System.Globalization;
using System.IO;
using System.Xml.Xsl;

namespace Ex1.CreatingAndManipulatingXML
{
    class CreateXML
    {
        //string culture = catalogXML.DocumentElement.Attributes["culture"].Value;
        //CultureInfo numberFormat = new CultureInfo(culture);

        static void Main(string[] args)
        {
            //Ex1CreateXMLCatalog();
            //Ex2ExtractArtistAndNumOfAlbums();
            //Ex3ExtractArtistAndNumOfAlbumsXPath();
            //Ex4RemoveAlbumWithHighPrice();
            //Ex5ExtractAllSongNames();
            //Ex6ExtractSongsNames();
            //Ex7ParseTextWithDOM();
            //Ex8CreateXmlAlbum();
            //Ex9TraverseDirAndMakeXml();
            Ex10TraverseDirAndMakeXmlXDocument();
            //Ex11AlbumbsBefore5Years();
            //Ex12StyleSheetXSL();
        }

        //Ex12 - XML to HTML via XSL StyleSheet
        private static void Ex12StyleSheetXSL()
        {
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load("../../catalog.xsl");
            xslt.Transform("../../catalog.xml", "../../catalog.html");
        }

        //Ex11 - Albums before 5 years
        private static void Ex11AlbumbsBefore5Years()
        {
            //DOM
            XmlDocument xmlCatalog = new XmlDocument();
            xmlCatalog.Load("../../catalog.xml");
            int year = DateTime.Now.Year;
            year -= 5;
            string xPath = String.Format("albums/album[year <= {0}]", year);
            XmlNodeList albums = xmlCatalog.SelectNodes(xPath);
            foreach (XmlNode album in albums)
            {
                Console.WriteLine("Album: {0}, Price: {1}, Year: {2}", album["name"].InnerText, album["price"].InnerText,
                    album["year"].InnerText);
            }

            //LINQ
            XDocument xmlLinqCatalog = XDocument.Load("../../catalog.xml");
            var oldAlbums =
                from album in xmlLinqCatalog.Descendants("album")
                where Double.Parse(album.Element("year").Value) <= year
                select album;
            foreach (var album in oldAlbums)
            {
                Console.WriteLine("Album: {0}, Price: {1}, Year: {2}", album.Element("name").Value,
                    album.Element("price").Value, album.Element("year").Value);
            }
        }

        //Ex10 - Traverse dir and make xml file XDocument
        private static void Ex10TraverseDirAndMakeXmlXDocument()
        {
            string directoryName = @"E:\New Subs";
            DirectoryInfo startDirectory = new DirectoryInfo(directoryName);

            XDocument doc = new XDocument();
            XElement root = new XElement("info");
            TraverseDirectoryXDocument(startDirectory, root);
            doc.Add(root);
            doc.Save(@"C:\Users\E\Desktop\xdirectory.xml");
        }

        private static void TraverseDirectoryXDocument(DirectoryInfo info, XElement doc)
        {
            XElement dir = new XElement("directory", new XAttribute("path", info.FullName));
            doc.Add(dir);

            DirectoryInfo[] directories = info.GetDirectories();
            FileInfo[] files = info.GetFiles();

            foreach (var item in files)
            {
                dir.Add(new XElement("file", item.Name));
            }

            foreach (var item in directories)
            {
                TraverseDirectoryXDocument(item, doc);
            }
        }

        //Ex9 - Traverse dir and make xml file
        private static void Ex9TraverseDirAndMakeXml()
        {
            string directoryName = @"C:\Users\E\Desktop\Kristian Smilenov";
            string fileName = "../../directory.xml";
            Encoding encoding = Encoding.UTF8;
            DirectoryInfo startDirectory = new DirectoryInfo(directoryName);
            using (XmlTextWriter writer = new XmlTextWriter(fileName, encoding))
            {
                writer.Formatting = Formatting.Indented;
                writer.IndentChar = '\t';
                writer.Indentation = 1;

                writer.WriteStartDocument();
                writer.WriteStartElement("directories");

                TraverseDirectoryXmlWriter(startDirectory, writer);
            }
        }

        private static void TraverseDirectoryXmlWriter(DirectoryInfo info, XmlWriter writer)
        {
            writer.WriteStartElement("directory");
            writer.WriteAttributeString("path", info.FullName);

            DirectoryInfo[] directories = info.GetDirectories();
            FileInfo[] files = info.GetFiles();

            foreach (var item in files)
            {
                writer.WriteElementString("file", item.Name);
            }

            foreach (var item in directories)
            {
                TraverseDirectoryXmlWriter(item, writer);
            }
            writer.WriteEndElement();
        }

        //Ex8 - Create Album
        private static void Ex8CreateXmlAlbum()
        {
            Encoding encoding = Encoding.UTF8;
            using (XmlReader reader = XmlReader.Create("../../catalog.xml"))
            {
                using (XmlTextWriter writer = new XmlTextWriter("../../album.xml", encoding))
                {
                    writer.Formatting = Formatting.Indented;
                    writer.IndentChar = '\t';
                    writer.Indentation = 1;

                    writer.WriteStartDocument();
                    writer.WriteStartElement("library");
                    writer.WriteAttributeString("name", "Telerik Library");

                    string albumName = string.Empty;
                    string artistName = string.Empty;

                    while (reader.Read())
                    {
                        if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "name"))
                        {
                            albumName = reader.ReadElementString();
                        }
                        if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "artist"))
                        {
                            writer.WriteStartElement("album");
                            writer.WriteElementString("name", albumName);
                            writer.WriteElementString("artist", artistName);
                            writer.WriteEndElement();
                        }
                    }
                }
            }
        }

        //Ex7 - CreateXMLWithDOM
        private static void Ex7ParseTextWithDOM()
        {
            string[] lines = File.ReadAllLines("../../peopleInfo.txt");
            XmlDocument document = new XmlDocument();
            string[] infos;
            XmlNode root = document.CreateNode(XmlNodeType.Element, "people", string.Empty);

            foreach (string item in lines)
            {
                XmlNode person = document.CreateNode(XmlNodeType.Element, "person", string.Empty);
                XmlNode nameNode = document.CreateNode(XmlNodeType.Element, "name", string.Empty);
                XmlNode adressNode = document.CreateNode(XmlNodeType.Element, "adress", string.Empty);
                XmlNode telNode = document.CreateNode(XmlNodeType.Element, "tel", string.Empty);

                root.AppendChild(person);
                person.AppendChild(nameNode);
                person.AppendChild(adressNode);
                person.AppendChild(telNode);

                infos = item.Split(',');
                nameNode.AppendChild(document.CreateTextNode(infos[0]));
                adressNode.AppendChild(document.CreateTextNode(infos[1]));
                telNode.AppendChild(document.CreateTextNode(infos[2]));

            }
            document.AppendChild(root);
            document.Save("../../people.xml");
        }

        //Ex6 - Extract All Song Names
        private static void Ex6ExtractSongsNamesLINQ()
        {
            XDocument xmlCatalog = XDocument.Load("../../catalog.xml");
            var songTitles =
                from album in xmlCatalog.Descendants("song")
                select album.Element("title").Value;

            foreach (var item in songTitles)
            {
                Console.WriteLine(item);
            }
        }

        //Ex5 - Song titles in the catalog
        private static void Ex5ExtractAllSongNames()
        {
            Console.WriteLine("All song titles in the catalog:");
            using (XmlReader reader = XmlReader.Create("../../catalog.xml"))
            {
                while (reader.Read())
                {
                    if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "title"))
                    {
                        Console.WriteLine(reader.ReadElementString());
                    }
                }
            }
        }

        //Ex4 - Delete Albums With Price More Than 20
        private static void Ex4RemoveAlbumWithHighPrice()
        {
            XmlDocument xmlCatalog = new XmlDocument();
            xmlCatalog.Load("../../catalog.xml");

            string xPathQuery = "albums/album[price > 20]";
            XmlNodeList nodesToDelete = xmlCatalog.SelectNodes(xPathQuery);

            foreach (XmlNode node in nodesToDelete)
            {
                xmlCatalog.SelectSingleNode("albums").RemoveChild(node);
            }

            xmlCatalog.Save("../../newCatalog.xml");
        }

        //Ex3 - Extract defferent artists and number of albums - XPath
        private static void Ex3ExtractArtistAndNumOfAlbumsXPath()
        {
            XmlDocument xmlCatalog = new XmlDocument();
            xmlCatalog.Load("../../catalog.xml");
            string xPathQuery = "/albums/album/artist";

            Dictionary<string, int> dict = new Dictionary<string, int>();

            XmlNodeList artistList = xmlCatalog.SelectNodes(xPathQuery);
            foreach (XmlNode artistNode in artistList)
            {
                string currentArtist = artistNode.InnerText;
                if (!dict.ContainsKey(currentArtist))
                {
                    dict.Add(currentArtist, 0);
                }
                dict[currentArtist] += 1;
            }

            foreach (var key in dict.Keys)
            {
                Console.WriteLine("Artist: {0}, Albums: {1}", key, dict[key]);
            }
        }

        //Ex2 - Extract defferent artists and number of albums
        private static void Ex2ExtractArtistAndNumOfAlbums()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("../../catalog.xml");

            //Console.WriteLine("Loaded XML document:");
            //Console.WriteLine(doc.OuterXml);
            //Console.WriteLine();

            Dictionary<string, int> dict = new Dictionary<string, int>();
            XmlNode rootNode = doc.DocumentElement;

            foreach (XmlNode node in rootNode.ChildNodes)
            {
                string currentArtist = node["artist"].InnerText;
                if (!dict.ContainsKey(currentArtist))
                {
                    dict.Add(currentArtist, 0);
                }
                dict[currentArtist] += 1;
            }

            foreach (var key in dict.Keys)
            {
                Console.WriteLine("Artist: {0}, Albums: {1}", key, dict[key]);
            }
        }

        //Ex1 - Create catalog.xml with some info
        private static void Ex1CreateXMLCatalog()
        {
            XElement catalogXML = new XElement("albums", new XAttribute("culture", "en-US"),
            new XElement("album",
                new XElement("name", "Euphoria"),
                new XElement("artist", "Enrique Iglesias"),
                new XElement("year", "2004"),
                new XElement("producer", "SPT"),
                new XElement("price", "40.5"),
                new XElement("songs",
                    new XElement("song",
                        new XElement("title", "I like It"),
                        new XElement("duration", "3.40")
                        ),
                    new XElement("song",
                        new XElement("title", "Heartbeat"),
                        new XElement("duration", "4.12")
                        ),
                    new XElement("song",
                        new XElement("title", "Ayer"),
                        new XElement("duration", "3.50")
                        )
                    )
                ),
                new XElement("album",
                new XElement("name", "Pesho's Album"),
                new XElement("artist", "Pesho"),
                new XElement("year", "2002"),
                new XElement("producer", "STA"),
                new XElement("price", "12.5"),
                new XElement("songs",
                    new XElement("song",
                        new XElement("title", "I am the best"),
                        new XElement("duration", "2.40")
                    ),
                    new XElement("song",
                        new XElement("title", "You are the best"),
                        new XElement("duration", "4.12")
                        )
                    )
                ),
                new XElement("album",
                new XElement("name", "Niki's Album"),
                new XElement("artist", "Niki"),
                new XElement("year", "2011"),
                new XElement("producer", "ABBA"),
                new XElement("price", "5.5"),
                new XElement("songs",
                    new XElement("song",
                        new XElement("title", "U Suck"),
                        new XElement("duration", "22.40")
                        )
                    )
                )
                ,
                new XElement("album",
                new XElement("name", "Niki's Second Album"),
                new XElement("artist", "Niki"),
                new XElement("year", "2012"),
                new XElement("producer", "ABBA"),
                new XElement("price", "6.5"),
                new XElement("songs",
                    new XElement("song",
                        new XElement("title", "U Suck 2"),
                        new XElement("duration", "2.40")
                        )
                    )
                )
            );


            //System.Console.WriteLine(catalogXML);

            catalogXML.Save("../../catalog.xml");
        }
    }
}
